<template>
	<view
		class="u-avatar"
		:class="[`u-avatar--${shape}`]"
		:style="[
			{
				backgroundColor:
					text || icon
						? randomBgColor
							? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)]
							: bgColor
						: 'transparent',
				width: $u.addUnit(size),
				height: $u.addUnit(size)
			},
			$u.addStyle(customStyle)
		]"
		@tap="clickHandler"
	>
		<slot>
			<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU  -->
			<open-data
				v-if="mpAvatar && allowMp"
				type="userAvatarUrl"
				:style="[
					{
						width: $u.addUnit(size),
						height: $u.addUnit(size)
					}
				]"
			/>
			<!-- #endif -->
			<!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU  -->
			<template v-if="mpAvatar && allowMp"></template>
			<!-- #endif -->
			<u-icon v-else-if="icon" :name="icon" :size="fontSize" :color="color"></u-icon>
			<u--text
				v-else-if="text"
				:text="text"
				:size="fontSize"
				:color="color"
				align="center"
				customStyle="justify-content: center"
			></u--text>
			<image
				class="u-avatar__image"
				v-else
				:class="[`u-avatar__image--${shape}`]"
				:src="avatarUrl || defaultUrl"
				:mode="mode"
				@error="errorHandler"
				:style="[
					{
						width: $u.addUnit(size),
						height: $u.addUnit(size)
					}
				]"
			></image>
		</slot>
	</view>
</template>

<script>
import props from './props.js'
import mpMixin from '../../libs/mixin/mpMixin.js'
import mixin from '../../libs/mixin/mixin.js'
const base64Avatar =
	''
/**
 * Avatar  头像
 * @description 本组件一般用于展示头像的地方，如个人中心，或者评论列表页的用户头像展示等场所。
 * @tutorial https://www.uviewui.com/components/avatar.html
 *
 * @property {String}			src				头像路径，如加载失败，将会显示默认头像(不能为相对路径)
 * @property {String}			shape			头像形状  （ circle (默认) | square）
 * @property {String | Number}	size			头像尺寸，可以为指定字符串(large, default, mini)，或者数值 （默认 40 ）
 * @property {String}			mode			头像图片的裁剪类型，与uni的image组件的mode参数一致，如效果达不到需求，可尝试传widthFix值 （默认 'scaleToFill' ）
 * @property {String}			text			用文字替代图片，级别优先于src
 * @property {String}			bgColor			背景颜色，一般显示文字时用 （默认 '#c0c4cc' ）
 * @property {String}			color			文字颜色 （默认 '#ffffff' ）
 * @property {String | Number}	fontSize		文字大小  （默认 18 ）
 * @property {String}			icon			显示的图标
 * @property {Boolean}			mpAvatar		显示小程序头像，只对百度，微信，QQ小程序有效  （默认 false ）
 * @property {Boolean}			randomBgColor	是否使用随机背景色  （默认 false ）
 * @property {String}			defaultUrl		加载失败的默认头像(组件有内置默认图片)
 * @property {String | Number}	colorIndex		如果配置了randomBgColor为true，且配置了此值，则从默认的背景色数组中取出对应索引的颜色值，取值0-19之间
 * @property {String}			name			组件标识符  （默认 'level' ）
 * @property {Object}			customStyle		定义需要用到的外部样式
 *
 * @event    {Function}        click       点击组件时触发   index: 用户传递的标识符
 * @example  <u-avatar :src="src" mode="square"></u-avatar>
 */
export default {
	name: 'u-avatar',
	// #ifndef MP
	emits: ['click'],
	// #endif
	mixins: [mpMixin, mixin, props],
	data() {
		return {
			// 如果配置randomBgColor参数为true，在图标或者文字的模式下，会随机从中取出一个颜色值当做背景色
			colors: [
				'#ffb34b',
				'#f2bba9',
				'#f7a196',
				'#f18080',
				'#88a867',
				'#bfbf39',
				'#89c152',
				'#94d554',
				'#f19ec2',
				'#afaae4',
				'#e1b0df',
				'#c38cc1',
				'#72dcdc',
				'#9acdcb',
				'#77b1cc',
				'#448aca',
				'#86cefa',
				'#98d1ee',
				'#73d1f1',
				'#80a7dc'
			],
			avatarUrl: this.src,
			allowMp: false
		}
	},
	watch: {
		// 监听头像src的变化，赋值给内部的avatarUrl变量，因为图片加载失败时，需要修改图片的src为默认值
		// 而组件内部不能直接修改props的值，所以需要一个中间变量
		src: {
			immediate: true,
			handler(newVal) {
				this.avatarUrl = newVal
				// 如果没有传src，则主动触发error事件，用于显示默认的头像，否则src为''空字符等的时候，会无内容展示
				if (!newVal) {
					this.errorHandler()
				}
			}
		}
	},
	computed: {
		imageStyle() {
			const style = {}
			return style
		}
	},
	created() {
		this.init()
	},
	methods: {
		init() {
			// 目前只有这几个小程序平台具有open-data标签
			// 其他平台可以通过uni.getUserInfo类似接口获取信息，但是需要弹窗授权(首次)，不合符组件逻辑
			// 故目前自动获取小程序头像只支持这几个平台
			// #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
			this.allowMp = true
			// #endif
		},
		// 判断传入的name属性，是否图片路径，只要带有"/"均认为是图片形式
		isImg() {
			return this.src.indexOf('/') !== -1
		},
		// 图片加载时失败时触发
		errorHandler() {
			this.avatarUrl = this.defaultUrl || base64Avatar
		},
		clickHandler() {
			this.$emit('click', this.name)
		}
	}
}
</script>

<style lang="scss" scoped>
@import '../../libs/css/components.scss';

.u-avatar {
	@include flex;
	align-items: center;
	justify-content: center;

	&--circle {
		border-radius: 100px;
	}

	&--square {
		border-radius: 4px;
	}

	&__image {
		&--circle {
			border-radius: 100px;
		}

		&--square {
			border-radius: 4px;
		}
	}
}
</style>
